/*
 *  Copyright 2020-2025 the original author or authors.
 *  You cannot use this file unless authorized by the author.
 */

package org.ipig.commons.helper;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.bson.Document;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 请在此处添加注释
 *
 * @author <a href="mailto:comchnts@163.com">chinats</a>
 * @version $$Id$$
 * @since 1.0
 */
@Slf4j
public class PojoHelper {
    /**
     * toDocument
     *
     * @param obj Object
     * @return Document
     */
    public static Document toDocument(final Object obj) {
        return toMap(obj, Document.class);
    }

    /**
     * toJSONObject
     *
     * @param obj Object
     * @return JSONObject
     */
    public static JSONObject toJSONObject(final Object obj) {
        return toMap(obj, JSONObject.class);
    }

    /**
     * toHashMap
     *
     * @param obj Object
     * @return HashMap
     */
    public static HashMap toHashMap(final Object obj) {
        return toMap(obj, HashMap.class);
    }

    /**
     * toLinkedHashMap
     *
     * @param obj Object
     * @return LinkedHashMap
     */
    public static LinkedHashMap toLinkedHashMap(final Object obj) {
        return toMap(obj, LinkedHashMap.class);
    }

    /**
     * toMap
     *
     * @param obj   Object
     * @param clazz Class 注 clazz extends Map<String, Object
     * @return Map<String, Object>
     */
    public static <T extends Map> T toMap(final Object obj, Class<T> clazz) {
        T map = null;
        try {
            map = (T) clazz.newInstance();
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propDescriptorArgs = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor prop : propDescriptorArgs) {
                String name = prop.getName();
                if (StringUtils.equalsIgnoreCase(name, "class")) {
                    continue;
                }
                Method readMethod = prop.getReadMethod();
                Object value = null;
                try {
                    value = readMethod != null ? readMethod.invoke(obj) : null;
                } catch (Exception e) {
                    e.printStackTrace();
                }
                map.put(name, value);
            }
        } catch (IntrospectionException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        return map;
    }
}
